﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Net;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Windows.Forms;

namespace OnlineScan
{
    public partial class Scaner : Form
    {
        #region DllImport

        [DllImport("Iphlpapi.dll")]
        private static extern int SendARP(Int32 dest, Int32 host, ref Int64 mac, ref Int32 length);

        [DllImport("Ws2_32.dll")]
        private static extern Int32 inet_addr(string ip);

        #endregion

        #region Attributes

        private static Form myForm=new Form();
        private static int len = 0;
        private static long StartIP = 0;
        private static long EndIP = 0;
        private static long IPCount = 0;
        private static long CurrentIP = 0;

        private static Thread[] ScanThread;
        private static bool ScanFinish = false; 
        private static bool IsPause = false;
        private static bool IsAbort = false;
        private delegate void DeleGateListView(ScanItem Item);
        private delegate void DeleGatebtnPause(bool b);
        private delegate void DeleGatebtnAbort(bool b);
        ManualResetEvent mre = new ManualResetEvent(true);

        public struct ScanItem
        {
            public string ip;
            public string status;
            public string mac;
            public string hostname;
        }

        #endregion

        #region Form

        public Scaner(Form obj)
        {
            InitializeComponent();
            myForm = obj;
        }

        private void Scaner_Shown(object sender, EventArgs e)
        {
           //EntryScan();
        }

        private void Scaner_FormClosing(object sender, FormClosingEventArgs e)
        {
            e.Cancel = true;

            if (!ScanFinish)
            {
                if (MessageBox.Show("正在进行扫描，要强制退出吗?", "系统提示", MessageBoxButtons.OKCancel, MessageBoxIcon.Question) == DialogResult.OK)
                {
                    try
                    {
                        for (int i = 0; i < GlobalAttrib.ThreadCount; i++)
                        {
                            ScanThread[i].Abort();
                        }
                    }
                    catch
                    {
                    }
                }
                else
                {
                    return;
                }
            }

            myForm.Visible = true;
            myForm.WindowState = FormWindowState.Normal;
            this.Dispose();
            e.Cancel = false;
        }

        #endregion

        #region Button

        

        #endregion

        #region Thread&Delegate

        

        

        
        

        private void SetbtnPause(bool b)
        {
            this.btnAbort.Enabled = false;
            if (!IsAbort)
            {
                if (IsPause)
                {
                    for (int i = 0; i < GlobalAttrib.ThreadCount; i++)
                    {
                        //ScanThread[i].Resume();
                    }
                    IsPause = false;
                    this.btnPause.Text = "暂停";
                    this.tsslResult.Text = "已暂停";

                }
                else
                {
                    for (int i = 0; i < GlobalAttrib.ThreadCount; i++)
                    {
                        //ScanThread[i].Suspend();
                    }
                    IsPause = true;
                    this.btnPause.Text = "恢复";
                }
            }
            this.btnAbort.Enabled = true;
        }

        

        

        #endregion 

        #region Method

        private ScanItem ApiGetMac(string ip)
        {
            ScanItem newItem = new ScanItem();
            newItem.ip = ip;

            Int64 macinfo = new Int64();
            Int32 length = 6;
            string mac = "";
            try
            {
                SendARP(inet_addr(ip), 0, ref macinfo, ref length);
                if (macinfo == 0) newItem.mac = "";
                mac = macinfo.ToString("X12");
                if (mac != "0000" && mac != "000000000000" && mac.Length == 12)
                {
                    newItem.mac = new string(new char[] { mac[10], mac[11], '-', mac[8], mac[9], '-', mac[6], mac[7], '-', mac[4], mac[5], '-', mac[2], mac[3], '-', mac[0], mac[1] });
                    newItem.status = "在线";
                }
                else
                {
                    newItem.mac = "";
                    newItem.status = "离线";
                }
            }
            catch 
            {
                newItem.mac = "";
                newItem.status = "离线";
            }

            try
            {
                IPHostEntry Host = Dns.GetHostEntry(ip);
                if (Host.HostName != ip) newItem.hostname = Host.HostName;
                else newItem.hostname = "";
            }
            catch
            {
            }

            return newItem;
        }   

        #endregion

        #region ToolStripMenuItem

        private void ToolStripMenuItem_SaveResult_Click(object sender, EventArgs e)
        {
            this.saveFileDialog1.ValidateNames = true;
            this.saveFileDialog1.Filter = "日志文件(*.log)|*.log|Excel文件(*.xls)|*.xls";
            this.saveFileDialog1.FilterIndex = 1;
            this.saveFileDialog1.DefaultExt = "log";
            this.saveFileDialog1.FileName = "";
            this.saveFileDialog1.AddExtension = true;
            if (this.saveFileDialog1.ShowDialog() == DialogResult.Cancel)
            {
                return;
            }

            if (this.saveFileDialog1.FileName.EndsWith(".xls"))
            {
                if (ListView2Excel(this.lvResult, this.saveFileDialog1.FileName))
                {
                    MessageBox.Show("导出成功！");
                }
                else
                {
                    MessageBox.Show("导出失败！");
                }
            }
            else
            {
                if (ListView2Text(this.lvResult, this.saveFileDialog1.FileName))
                {
                    MessageBox.Show("导出成功！");
                }
                else
                {
                    MessageBox.Show("导出失败！");
                }
            }
        }

        #endregion

        #region IPTrans

        

        private Int64 IP2Int(string ip)
        {
            Int64 newIP = 0;
            string[] IPs = ip.Split('.');
            try
            {
                newIP = Convert.ToInt64(IPs[0].PadLeft(3, '0') + IPs[1].PadLeft(3, '0') + IPs[2].PadLeft(3, '0') + IPs[3].PadLeft(3, '0'));
                return newIP;
            }
            catch
            {
                return 0;
            }
        }

        private string Int2IP(Int64 I)
        {
            string IP;
            string str = I.ToString().PadLeft(12, '0');
            IP = int.Parse(str.Substring(0, 3)).ToString() + "." + int.Parse(str.Substring(3, 3)).ToString() + "." + int.Parse(str.Substring(6, 3)).ToString() + "." + int.Parse(str.Substring(9, 3)).ToString();
            return IP;
        }

        #endregion

        #region ListView

        private void lvResult_ColumnClick(object sender, ColumnClickEventArgs e)
        {
            ListViewSort(this.lvResult, e.Column, 0);
        }

        /// <summary>
        /// 对ListView排序
        /// </summary>
        /// <param name="LV">ListView控件</param>
        /// <param name="ColumnIndex">要排序的列索引</param>
        /// <param name="SortType">排序方式：0自动 1升 2降</param>
        private void ListViewSort(ListView LV, int ColumnIndex, int SortType)
        {
            if (LV.Items.Count == 0) return;
            int j, ColumnCount = LV.Columns.Count;
            foreach (ListViewItem item in LV.Items)
            {
                item.UseItemStyleForSubItems = false;
                for (j = 0; j < ColumnCount; j++) item.SubItems[j].BackColor = Color.White;
                item.SubItems[ColumnIndex].BackColor = Color.WhiteSmoke;
            }

            string Asc = ((char)0x25bc).ToString().PadLeft(2, ' ');
            string Des = ((char)0x25b2).ToString().PadLeft(2, ' ');
            ColumnHeader CurColumn = LV.Columns[ColumnIndex];
            string ColumnText = CurColumn.Text.TrimEnd((char)0x25bc, (char)0x25b2, ' ');

            bool Sort = true; //默认升序
            if ((SortType == 2) || (SortType == 0 && CurColumn.Text.IndexOf(Des) > 0)) Sort = false; //降序
            foreach (ColumnHeader ch in LV.Columns) ch.Text = ch.Text.TrimEnd((char)0x25bc, (char)0x25b2, ' ');
            CurColumn.Text = ColumnText + ((Sort) ? Des : Asc);
            this.lvResult.ListViewItemSorter = new ListViewItemComparer(ColumnIndex, Sort);
            this.lvResult.Sort();
        }

        private bool ListView2Excel(ListView listView, string strFileName)
        {
            int rowNum = listView.Items.Count;
            int columnNum = listView.Items[0].SubItems.Count;
            int rowIndex = 1;
            int columnIndex = 0;
            if (rowNum == 0 || string.IsNullOrEmpty(strFileName))
            {
                return false;
            }
            if (rowNum > 0)
            {

                Microsoft.Office.Interop.Excel.Application xlApp = new Microsoft.Office.Interop.Excel.ApplicationClass();
                if (xlApp == null)
                {
                    MessageBox.Show("无法创建excel对象，可能您的系统没有安装excel");
                    return false;
                }
                xlApp.DefaultFilePath = "";
                xlApp.DisplayAlerts = true;
                xlApp.SheetsInNewWorkbook = 1;
                Microsoft.Office.Interop.Excel.Workbook xlBook = xlApp.Workbooks.Add(true);
                //将ListView的列名导入Excel表第一行
                foreach (ColumnHeader dc in listView.Columns)
                {
                    columnIndex++;
                    xlApp.Cells[rowIndex, columnIndex] = dc.Text;
                }
                //将ListView中的数据导入Excel中
                for (int i = 0; i < rowNum; i++)
                {
                    rowIndex++;
                    columnIndex = 0;
                    for (int j = 0; j < columnNum; j++)
                    {
                        columnIndex++;
                        //注意这个在导出的时候加了“\t” 的目的就是避免导出的数据显示为科学计数法。可以放在每行的首尾。
                        xlApp.Cells[rowIndex, columnIndex] = Convert.ToString(listView.Items[i].SubItems[j].Text) + "\t";
                    }
                }
                //例外需要说明的是用strFileName,Excel.XlFileFormat.xlExcel9795保存方式时 当你的Excel版本不是95、97 而是2003、2007 时导出的时候会报一个错误：异常来自 HRESULT:0x800A03EC。 解决办法就是换成strFileName, Microsoft.Office.Interop.Excel.XlFileFormat.xlWorkbookNormal。
                xlBook.SaveAs(strFileName, Microsoft.Office.Interop.Excel.XlFileFormat.xlWorkbookNormal, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Microsoft.Office.Interop.Excel.XlSaveAsAccessMode.xlExclusive, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing);
                xlApp = null;
                xlBook = null;
            }
            return true;
        }


        private bool ListView2Text(ListView listView, string strFileName)
        {
            FileStream fs = new FileStream(strFileName, FileMode.Append, FileAccess.Write, FileShare.Read);
            StreamWriter text = new StreamWriter(fs, Encoding.Default);
            string RecordLine = "";

            try
            {
                for (int i = 0; i < listView.Columns.Count; i++)
                {
                    RecordLine += listView.Columns[i].Text + "\t";
                }
                text.WriteLine(RecordLine);

                for (int i = 0; i < listView.Items.Count; i++)
                {
                    RecordLine = "";
                    for (int j = 0; j < listView.Columns.Count; j++)
                    {
                        RecordLine += listView.Items[i].SubItems[j].Text + "\t";
                    }
                    text.WriteLine(RecordLine);
                }
            }
            catch
            {
                return false;
            }

            text.Close();
            text.Dispose();
            fs.Close();
            fs.Dispose();
            return true;
        }

        public class ListViewItemComparer : System.Collections.IComparer
        {
            public bool sort_b;
            public SortOrder order = SortOrder.Ascending;

            private int col;

            public ListViewItemComparer()
            {
                col = 0;
            }

            public ListViewItemComparer(int column, bool sort)
            {
                col = column;
                sort_b = sort;
            }

            public int Compare(object x, object y)
            {
                if (sort_b)
                {
                    return String.Compare(((ListViewItem)x).SubItems[col].Text, ((ListViewItem)y).SubItems[col].Text);
                }
                else
                {
                    return String.Compare(((ListViewItem)y).SubItems[col].Text, ((ListViewItem)x).SubItems[col].Text);
                }
            }
        }

        #endregion
    }
}
